#ifndef __GD32F470VET6_BSP_H__
#define __GD32F470VET6_BSP_H__

#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <math.h>

#include "gd32f4xx.h"
#include "systick.h"
#include "scheduler.h"
#include "gd32f4xx_rcu.h"
#include "gd32f4xx_gpio.h"
#include "gd32f4xx_adc.h"
#include "gd32f4xx_usart.h"
#include "gd32f4xx_misc.h"
#include "gd32f4xx_dma.h"
#include "gd32f4xx_misc.h"
#include "gd32f4xx_i2c.h"
#include "gd32f4xx_spi.h"
#include "gd32f4xx_rtc.h"

#include "ebtn.h"
#include "oled.h"
#include "gd25qxx.h"
#include "sdio_sdcard.h"
#include "ff.h"
#include "diskio.h"

#include "led_app.h"
#include "btn_app.h"
#include "adc_app.h"
#include "usart_app.h"
#include "oled_app.h"
#include "tf_app.h"
#include "rtc_app.h"

/* SCHEDULER */
typedef struct
{
    void (*TaskFunc)(void);
    uint32_t task_interval;
    uint32_t last_run_tick;
} Task_t;

extern volatile uint32_t uwTick;
extern Task_t schedul_task[];
extern uint8_t task_num;

/* LED */
#define LED_NUM                     6U

#define LED_GPIO_PORT               GPIOD
#define LED_GPIO_CLK                RCU_GPIOD

#define LED1_PIN                    GPIO_PIN_8
#define LED2_PIN                    GPIO_PIN_9
#define LED3_PIN                    GPIO_PIN_10
#define LED4_PIN                    GPIO_PIN_11
#define LED5_PIN                    GPIO_PIN_12
#define LED6_PIN                    GPIO_PIN_13

extern uint8_t ucLed[LED_NUM];

void LedDisp(uint8_t *ucLed);

/* BTN */
#define BTN_NUM                     6U

#define BTNB_GPIO_PORT              GPIOB
#define BTNB_GPIO_CLK               RCU_GPIOB
#define BTNE_GPIO_PORT              GPIOE
#define BTNE_GPIO_CLK               RCU_GPIOE

#define BTN1_PIN                    GPIO_PIN_0
#define BTN2_PIN                    GPIO_PIN_7
#define BTN3_PIN                    GPIO_PIN_9
#define BTN4_PIN                    GPIO_PIN_11
#define BTN5_PIN                    GPIO_PIN_13
#define BTN6_PIN                    GPIO_PIN_15

// 定义用户按键ID枚举类型
typedef enum
{
    // 定义按键ID
    USER_BUTTON_1 = 0,
    USER_BUTTON_2,
    USER_BUTTON_3,
    USER_BUTTON_4,
    USER_BUTTON_5,
    USER_BUTTON_6,
    USER_BUTTON_MAX,

    // 定义组合按键ID
    USER_BUTTON_COMBO_1 = 100,
    USER_BUTTON_COMBO_2,
    USER_BUTTON_COMBO_MAX,
} UserButtenId_t;

/* ADC */
#define ADC0_GPIO_PORT              GPIOC
#define ADC0_GPIO_CLK               RCU_GPIOC

#define ADC0_GPIO_PIN               GPIO_PIN_0

#define ADC0_DATA_ADDRESS           (uint32_t)(&ADC_RDATA(ADC0))

#define ADC0_BUFFER_SIZE            32

extern uint16_t adc0_value[32];
extern float adc0_voltage;

/* USART0 */
#define USART0_GPIO_PORT            GPIOA
#define USART0_GPIO_CLK             RCU_GPIOA

#define USART0_TX_PIN               GPIO_PIN_9
#define USART0_RX_PIN               GPIO_PIN_10

#define USART0_DATA_ADDRESS         ((uint32_t)&USART_DATA(USART0))

#define USART0_BAUDRATE             115200U
#define USART0_BUFFER_SIZE          1024
#define USART0_TIMEOUT_MS           100

extern uint8_t usart0_rx_buffer_dma[USART0_BUFFER_SIZE];     // USART0 DMA Rx Buffer
extern uint8_t usart0_rx_buffer_proc[USART0_BUFFER_SIZE];    // USART0 Rx ProcBuffer

extern volatile uint8_t usart0_rx_flag;

uint32_t Usart0Printf(const char *format, ...);

/* USART1 */
#define USART1_GPIO_PORT            GPIOA
#define USART1_GPIO_CLK             RCU_GPIOA

#define RS485_CS_PIN                GPIO_PIN_1
#define USART1_TX_PIN               GPIO_PIN_2
#define USART1_RX_PIN               GPIO_PIN_3

#define USART1_DATA_ADDRESS         ((uint32_t)&USART_DATA(USART1))

#define USART1_BAUDRATE             115200U
#define USART1_BUFFER_SIZE          1024
#define USART1_TIMEOUT_MS           100

extern uint8_t usart1_rx_buffer_dma[USART1_BUFFER_SIZE];
extern uint8_t usart1_rx_buffer_proc[USART1_BUFFER_SIZE];

extern volatile uint8_t usart1_rx_flag;

uint32_t Usart1Printf(const char *format, ...);

/* OLED */
#define I2C0_OWN_ADDRESS7           0x72
#define I2C0_DATA_ADDRESS           (uint32_t)&I2C_DATA(I2C0)

#define OLED_GPIO_PORT              GPIOB
#define OLED_GPIO_CLK               RCU_GPIOB
#define OLED_DAT_PIN                GPIO_PIN_9
#define OLED_CLK_PIN                GPIO_PIN_8

extern uint8_t oled_batch_buffer[258];       // 批量传输缓冲区
extern uint16_t oled_buffer_index;           // 当前缓冲区索引
extern uint16_t oled_buffer_threshold;       // 缓冲区刷新阈值

int OledDrawStr(uint8_t x, uint8_t y, const char *format, ...);

/* RTC */
#define RTC_CLOCK_SOURCE_IRC32K
#define BKP_VALUE                   0x32F0

extern rtc_parameter_struct ucRtc;
extern uint32_t prescaler_a;
extern uint32_t prescaler_s;

uint8_t BcdToDec(uint8_t bcd);
uint8_t DecToBcd(uint8_t dec);
void SetRtc(rtc_parameter_struct *current_time);
void ReadRtc(rtc_parameter_struct *current_time);

/* FLASH */
#define FLASH_GPIO_PORT             GPIOB
#define FLASH_GPIO_CLK              RCU_GPIOB

#define SPI1_NSS_PIN                GPIO_PIN_12
#define SPI1_SCK_PIN                GPIO_PIN_13
#define SPI1_MISO_PIN               GPIO_PIN_14
#define SPI1_MOSI_PIN               GPIO_PIN_15

/* TF card */
extern FATFS fs;

/* System Init */
void SysInit(void);

#endif  /* __GD32F470VET6_BSP_H__ */
